/*
 * Copyright (c) 1999 by Visa International Service Association, all rights reserved.
 * Visa is a registered trademark of Visa International Service Association. This
 * software is the property of Visa International Service Association and is protected
 * under the copyright, trade secret and confidentiality laws of the United States
 * and other countries, including each of the countries in which it is licensed.
 */

// $Date: 12/31/99

package visa.openplatform;

import javacard.framework.*;
import com.wk.javacard.vnative.VN;
import org.globalplatform.*;

/**
 * This defines the interface of a privileged system class that represents an Application Provider on a card.
 * The class implementing this interface must be declared a Shareable Interface Object (see the JCRE document
 * in Java Card 2.1). This class offers cryptographic services, key management services, runtime messaging
 * support, and secure loading services to applets from the same Application Provider. Prior to using this
 * interface, an application is required to obtain a handle to it's associated Security Domain by invoking
 * the <code>OPSystem.getSecurityDomain()</code> method.
 */

class ISDSecurityDomain implements ProviderSecurityDomain {

	ISDSecurityDomain(){
		VN.native_FrameWork_JCSystem_setJCREEntry(this, false);
	}
    /**
     * This method is used to close the Secure Channel that was previously opened with the openSecureChannel()
     * method. Specifically, to erase any secure information relating to the Secure Channel.
     *
     * @param channel   Secure channel number
     */
    public void closeSecureChannel(byte channel)
    {
		VN.native_OP_resetSecurity();
    }

    /**
     * This method is used to decrypt and verify a key received by the application within a Secure Channel.
     *
     * @return          TRUE if key has been verified, FALSE otherwise
     * @param channel   Secure Channel number
     * @param apdu      The APDU handle
     * @param offset    Offset within the APDU buffer where the key set data field can be retrieved
     */
    public boolean decryptVerifyKey(byte channel, APDU apdu, short offset)
    {
    	byte[] buffer = apdu.getBuffer();
    	try
    	{
			VN.native_OP_201_getISDSecureChannel().decryptData(buffer, (short)(offset+2), (short)(buffer[(short)(offset+1)]&0xFF));
			return VN.native_OP_201_decryptVerifyKey_CT();
		}catch (Exception e)
		{
		}
		return false;
    }

    /**
     * This method opens a Secure Channel for an applet and returns the newly opened channel number. The
     * supplied APDU must contain the command used to retrieve data from the card that will be used by the
     * off-card entity to authenticate the card.
     *
     * This method also prepares the response to this command. The Security Domain that the applet belongs
     * to is responsible for the channel number allocation. The channel '0' is reserved, and channels 1
     * through 127 are available for the applet's use.
     *
     * @return          Channel number
     * @param apdu      The APDU handle
     */
    public byte openSecureChannel(APDU apdu)
    {
    	VN.native_OP_201_getISDSecureChannel().processSecurity(apdu);
		return (byte)0x01;
	}


    /**
     * This method is used to process the APDU buffer received within a Secure Channel.
     * The processing is according to the requirements for integrity and confidentiality that are
     * established when a Secure Channel is opened. The resultant APDU contains the command as if
     * it were received outside of a Secure Channel.
     *
     * @param channel   Secure Channel number
     * @param apdu      The APDU handle
     */
    public void unwrap(byte channel, APDU apdu)
    {
    	if (VN.native_OP_getSecurityLevel()==SecureChannel.NO_SECURITY_LEVEL)
    		ISOException.throwIt((short)0x6985);
    	byte[] buff = apdu.getBuffer();
    	VN.native_OP_201_getISDSecureChannel().unwrap(buff, (short)0, (short)(5 + (buff[ISO7816.OFFSET_LC]&0xFF)));
    }


    /**
     * This method is used to authenticate the off-card entity by verifying the contents of the APDU command.
     *
     * @param channel   Secure Channel number
     * @param apdu 	    The APDU handle
     */
    public void verifyExternalAuthenticate(byte channel, APDU apdu)
    {
    	VN.native_OP_201_getISDSecureChannel().processSecurity(apdu);
    }


}